namespace AutoTest.Core.Messaging
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using Ninject.Core;

    public abstract class TypeScanningModule : StandardModule
    {
        readonly Assembly _assembly;

        protected TypeScanningModule(Assembly assembly)
        {
            _assembly = assembly;
        }

        public override void Load()
        {
            foreach(var concreteType in GetConcereteTypes())
            {
                foreach(var interfaceType in concreteType.GetInterfaces())
                {
                    if(interfaceType.GetInterfaces().Contains(typeof(IMessageConsumer)))
                    {
                        //bind with not default binding
                        Bind(interfaceType).To(concreteType).OnlyIf(c => c.Service.Name == "asdf");
                    }
                }
            }
        }

        IEnumerable<Type> GetConcereteTypes()
        {
            foreach(var type in _assembly.GetTypes())
            {
                if(type.IsInterface || type.IsAbstract)
                {
                    continue;
                }
                yield return type;
            }
        }
    }

    public class MessageModule : StandardModule
    {
        readonly Assembly _assembly;


        public MessageModule(Assembly assembly)
        {
            _assembly = assembly;
        }

        public override void Load()
        {
            Bind<IMessageBus>().To<MessageBus>();
            Kernel.Load(new Scanner(_assembly));
        }

        class Scanner : TypeScanningModule
        {
            public Scanner(Assembly assembly) : base(assembly)
            {
            }
        }
    }
}